<template>
    <div id="app2">
        <!-- 加载 -->
        <div class="loading" v-if="!Trees">
            <p>加载中</p>
        </div>
        <!-- 主体 -->
        <div
            class="main"
            v-else
            v-loading="loadContent"
            element-loading-text="全力加载中..."
        >
            <!-- 左侧 -->
            <div :class="{ leftMenu: true, leftMenuHide: menuShow }" v-cloak>
                <!-- 菜单 -->
                <el-tabs v-model="treeMenu">
                    <!-- 文件树 -->
                    <el-tab-pane label="文件" name="文件">
                        <div class="trees">
                            <!-- 文件列表头部 -->
                            <div class="treesHead">
                                <a :href="Trees.giteeURL" target="_blank">
                                    <i class="fa fa-folder-open"></i>
                                    {{ Trees.sha }}
                                </a>
                            </div>
                            <!-- 文件列表 -->
                            <div
                                :class="{
                                    treesItem: true,
                                    treesItemActive: index == contentSelectIndex
                                }"
                                v-for="(item, index) in Trees.tree"
                                @click="getContents(item.path, index)"
                                :key="index"
                            >
                                <i class="fa fa-file-code-o"></i>
                                {{ item.path }}
                            </div>
                        </div>
                    </el-tab-pane>
                    <!-- 目录 -->
                    <el-tab-pane label="目录" name="目录">
                        <div class="contentTrees">
                            <div
                                :class="{
                                    contentItem: true,
                                    contentItemActive: index == menuSelectIndex,
                                    [item.tagName]: true
                                }"
                                v-for="(item, index) in menuData"
                                :key="index"
                                @click="menuSelect(index)"
                            >
                                {{ item.textContent }}
                            </div>
                        </div>
                    </el-tab-pane>
                </el-tabs>
                <!-- 底部菜单 -->
                <div class="bottomMenu">
                    <div content="回到顶部" @click="backTop(0)">
                        <i class="fa fa-angle-up"></i>
                    </div>
                    <div
                        content="收起菜单"
                        @click="menuShowOrHide"
                        v-if="menuShow"
                    >
                        <i class="fa fa-angle-left"></i>
                    </div>
                    <div content="展开菜单" @click="menuShowOrHide" v-else>
                        <i class="fa fa-angle-right"></i>
                    </div>
                    <div content="更换主题" @click="loadTheme">
                        <i class="fa fa-star-half-empty"></i>
                    </div>
                    <div content="编辑本文" @click="editorState = !editorState">
                        <i class="fa fa-pencil"></i>
                    </div>
                    <div content="分享此笔记" @click="shareNote">
                        <el-icon><Share /></el-icon>
                    </div>
                    <!-- <div content="设置" @click="openSetting">
                            <i class="fa fa-cog"></i>
                        </div> -->
                </div>
            </div>
            <!-- 手机端遮罩 -->
            <div
                :class="{ peBlack: true, peBlackHide: menuShow }"
                @click="menuShowOrHide"
            ></div>
            <!-- 内容 -->
            <div class="body">
                <!-- 编辑界面 -->
                <div class="editor" :class="{ editorShow: editorState }">
                    <!-- 编辑菜单 -->
                    <div class="editorMenu">
                        <div @click="saveEdit">
                            <el-tooltip
                                class="box-item"
                                effect="dark"
                                content="保存"
                                placement="bottom"
                            >
                                <i class="fa fa-cloud-upload"></i>
                            </el-tooltip>
                        </div>
                    </div>
                    <!-- 编辑框 -->
                    <!-- <textarea v-model="markdown"></textarea> -->
                    <div id="container"></div>
                </div>
                <!-- 文章内容 -->
                <div
                    :class="{ content: true, contentHide: !menuShow }"
                    id="content"
                    :style="'padding-top:' + contentPaddingTop + 'px;'"
                >
                    <div v-html="content"></div>
                </div>
            </div>
        </div>
    </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, watch } from "vue";
import axios from "axios";
import { Base64 } from "js-base64";
import MarkdownIt from "markdown-it";
import Viewer from "viewerjs";
import "viewerjs/dist/viewer.css";
import themeUtil from "@/utils/themeUtil";
import hljs from "highlight.js";
import Clipboard from "clipboard";
import { Share } from "@element-plus/icons-vue";
import * as monaco from "monaco-editor";

const testValue = ref("# wdnmd");

watch(
    () => testValue.value,
    () => {
        console.log(testValue.value);
    }
);

onMounted(() => {
    themeUtil.load();
    getTrees();

    // 根据屏幕宽度决定菜单收缩状态
    screenWidthMenuState();
    // 屏幕宽度发生变化
    window.onresize = () => {
        screenWidthMenuState();
    };
});

const md = new MarkdownIt();

// 主题获取
// const localThemeSave = ref(window.localStorage.getItem("theme"));

const config = {
    // Gitee 配置
    gitee: {
        // 账号
        owner: "n0ts",
        // 仓库名称
        repo: "note",
        // 分支名
        sha: "master"
    },
    // 后端地址
    serverBase: "https://api.n0ts.top/api/gitee",
    // 主题配置
    Themes: ["default-light", "default-dark"]
};

const api = {
    // 获取文件数
    getTree: `/repos/${config.gitee.owner}/${config.gitee.repo}/git/trees/${config.gitee.sha}?recursive=1`,
    // 获取具体文件内容
    getContent: `/repos/${config.gitee.owner}/${config.gitee.repo}/contents/`
};

// 仓库下的所有文件
const Trees = ref<any>(null);
// 当前内容
const content = ref("");
// 当前选择的文件
const contentSelectIndex = ref<number>(-1);
// 菜单默认选择
const treeMenu = ref("文件");
// 笔记加载遮罩
const loadContent = ref(false);
// 文章目录数据
const menuData = ref<any>(null);
// 当前目录选择索引
const menuSelectIndex = ref(0);
// 菜单是否展开
const menuShow = ref(true);
// 计算屏幕长度，防抖
const timeOut = ref();
// 计算内容滚动距离，防抖
const timeOut2 = ref();
// 子文件夹路径
const childFile = ref();
// 图片集
const ViewerUtil = ref();
// 内容页内边高度
const contentPaddingTop = ref(0);
// 当前 markdown 内容
const markdown = ref();
// 是否启用编辑
const editorState = ref();
// 文章内容 Dom
const contentDom = ref();

/**
 * 加载主题
 */
function loadTheme() {
    themeUtil.switchTheme();
}

/**
 * 获取目录 Tree
 */
function getTrees() {
    axios
        .post(config.serverBase, {
            method: "GET",
            url: api.getTree
        })
        .then((resData) => {
            Trees.value = resData.data.data;

            // 数据验证
            if (!Trees.value.tree) {
                content.value = `## 仓库是空的？\n快去检查吧！`;
                // 设置内容
                return setContent();
            }

            // 数据过滤，保留 md 后缀的文件
            Trees.value.tree = Trees.value.tree
                .map((item: any) => {
                    // 取消显示 README
                    if (item.path == "README.md") {
                        return null;
                    }
                    if (
                        item.path.substring(
                            item.path.length - 3,
                            item.path.length
                        ) == ".md"
                    ) {
                        return item;
                    }
                })
                .filter(Boolean);

            // 获取仓库具体路径下的内容
            const querys = getQueryParams();
            if (querys.path) {
                getContents(querys.path);
            } else {
                getContents("README.md");
            }
        })
        .catch((err) => {
            console.error("报错啦！错误信息：", err);
        });
}

/**
 * 获取仓库具体路径下的内容
 * @param {*} path 文件名
 * @returns 文件数据
 */
function getContents(path: string, index?: number) {
    // 索引修改 & 是否重复
    if (contentSelectIndex.value == index) {
        return;
    }
    if (index != null) {
        contentSelectIndex.value = index;
    } else {
        for (let i = 0; i < Trees.value.tree.length; i++) {
            if (Trees.value.tree[i].path == path) {
                contentSelectIndex.value = i;
                break;
            }
        }
    }

    // 数据验证
    if (!path) {
        return;
    }

    // 子文件夹路径获取
    childFile.value = path.includes("/")
        ? path.substring(0, path.lastIndexOf("/"))
        : "";

    // 加载遮罩启动
    loadContent.value = true;

    axios
        .post(config.serverBase, {
            method: "GET",
            url: api.getContent + encodeURIComponent(path)
        })
        .then((res) => {
            loadContent.value = false;
            // 存储 markdown 格式
            markdown.value = content.value = Base64.decode(
                res.data.data.content
            );

            // 是否存在内容
            if (!content.value || content.value.trim() == "") {
                content.value = `## 这里空空如也～\n没写点东西还好意思上传？`;
            }

            // 设置内容
            setContent();

            // 滚动条回到顶部
            backTop(0);
        })
        .catch((err) => {
            loadContent.value = false;
            console.log("报错啦", err);
        });
}

/**
 * 设置内容
 */
function setContent() {
    // 转换为 html，超链接新建页面打开
    content.value = md
        .render(content.value)
        .replace(/<a /g, "<a target='_blank' ");

    // 转换后是否为空
    if (!content.value || content.value.trim() == "") {
        content.value =
            "<h2>这里空空如也～</h2><p>没写点东西还好意思上传？</p>";
    }

    // 获取内容中全部图片的 src
    content.value.replace(
        /<img [^>]*src=['"]([^'"]+)[^>]*>/gi,
        (match, capture) => {
            // 是否为 url
            let testVol =
                // eslint-disable-next-line
                /^(http|https):\/\/(([\w-]+\.)+[\w-]+|localhost)(\/[\w-.\/?%&=]*)?$/.test(
                    capture
                );

            // 不是 url 则添加仓库链接
            if (!testVol) {
                let replacement = decodeURIComponent(
                    `https://api.n0ts.top/gitee/image?url=https://gitee.com/${config.gitee.owner}/${config.gitee.repo}/raw/${config.gitee.sha}${childFile.value}/${capture}`
                );
                content.value = content.value.replace(capture, replacement);
            }

            return match;
        }
    );

    setTimeout(() => {
        // 索引复原
        menuSelectIndex.value = 0;

        // 代码高亮
        hljsInit();

        // 获取文章目录
        getContentMenu();

        // 文章内图片查看加载
        loadImgView();

        // 监听内容区滚动条
        listenContentScroll();
    }, 0);
}

/**
 * 代码高亮
 */
async function hljsInit() {
    const dom: any = [];
    const codeBlocks = document.querySelectorAll("#content pre code");
    codeBlocks.forEach((cache) => {
        const item = cache as HTMLElement;
        if (item.getAttribute("class")?.includes("hljs")) {
            return;
        }
        const copyBtn = document.createElement("div");
        copyBtn.className = "copyBtn";
        copyBtn.innerHTML = "复制";
        copyBtn.setAttribute("code", item.innerText);
        copyBtn.addEventListener("click", (e) => {
            copyCode(e);
        });
        item.parentElement?.appendChild(copyBtn);
        hljs.highlightElement(item as HTMLElement);
        dom.push(item);
    });
    addCodeNum(dom);
}

/**
 * 添加代码行号
 */
function addCodeNum(dom: any) {
    for (let i = 0; i < dom.length; i++) {
        const enter = dom[i].innerHTML.replace(/\n/g, "</li><li>");
        dom[i].innerHTML = `<ol><li>${enter}</li></ol>`.replace(
            "<li></li></ol>",
            "</ol>"
        );
    }
}

/**
 * 复制代码块
 */
function copyCode(el: MouseEvent) {
    const code = (el.target as HTMLElement).getAttribute("code");
    if (code) {
        Clipboard.copy(code);
    }
}

/**
 * 获取文章目录
 */
function getContentMenu() {
    menuData.value = null;
    let dom = contentDom.value.querySelectorAll("h1, h2, h3, h4");
    menuData.value = [...dom].map((item) => {
        // 获取标签名，内容，距离顶边高度
        let { tagName, textContent, offsetTop } = item;
        return {
            tagName,
            textContent,
            offsetTop
        };
    });
}

/**
 * 文章内图片查看加载
 */
function loadImgView() {
    if (!ViewerUtil.value) {
        return (ViewerUtil.value = new Viewer(
            document.querySelector("#content") as HTMLElement
        ));
    }
    ViewerUtil.value.update();
}

/**
 * 监听内容区滚动条
 */
function listenContentScroll() {
    contentDom.value.addEventListener("scroll", (e: any) => {
        if (timeOut2.value) {
            clearTimeout(timeOut2.value);
        }
        timeOut2.value = setTimeout(() => {
            // 计算高度增加一丢丢
            let top = e.target.scrollTop + 30;

            // 实时获取标题元素
            let dom = contentDom.value.querySelectorAll("h1, h2, h3, h4");
            let trees = [...dom].map((item) => {
                return item.offsetTop;
            });

            // 第一个标题高度处理
            let oneTitle = window.getComputedStyle(dom[0], null).marginTop;
            oneTitle = Number(
                oneTitle.substring(0, oneTitle.length - 2)
            ).toString();
            if ((trees[0] - contentPaddingTop.value).toString() == oneTitle) {
                trees[0] = 0;
            }

            // 遍历判断当前高度对应标题位置
            for (let i = 0; i < trees.length; i++) {
                // 当滚动高度大于对应索引改变高亮
                if (top >= trees[i]) {
                    menuSelectIndex.value = i;
                }
            }
        }, 50);
    });
}

/**
 * 滚动条到指定位置
 */
function backTop(top: number) {
    if (!contentDom.value) {
        contentDom.value = document.querySelector("#content");
    }
    contentDom.value.scrollTo({
        top,
        behavior: "smooth"
    });
}

/**
 * 目录选择
 * @param {*} i 索引
 */
function menuSelect(i: number) {
    // 设置索引高亮
    menuSelectIndex.value = i;

    // 获取滚动高度
    let top = contentDom.value.querySelectorAll("h1, h2, h3, h4")[i].offsetTop;

    contentDom.value.scrollTo({
        top,
        behavior: "smooth"
    });
}

/**
 * 菜单展开与隐藏
 */
function menuShowOrHide() {
    menuShow.value = !menuShow.value;
}

/**
 * 根据屏幕宽度决定菜单收缩状态
 * 用于动态自适应
 */
function screenWidthMenuState() {
    if (timeOut.value) {
        clearTimeout(timeOut.value);
    }
    let state = document.body.clientWidth <= 820;
    timeOut.value = setTimeout(() => {
        // 当屏幕小于820 且 菜单是打开的情况下
        if (state && menuShow.value) {
            menuShowOrHide();
        }
    }, 100);
}

/**
 * 编辑框保存到码云
 */
function saveEdit() {
    console.log(1);
}

function getQueryParams() {
    var queryString = window.location.search;
    var params: any = {};

    if (!queryString) {
        return params;
    }

    queryString = queryString.substr(1); // 去除开头的问号字符
    var paramList = queryString.split("&");
    for (var i = 0; i < paramList.length; i++) {
        var param = paramList[i].split("=");
        var paramName = decodeURIComponent(param[0]);
        var paramValue = decodeURIComponent(param[1] || "");
        // 将参数名和值保存到对象中
        if (paramName) {
            params[paramName] = paramValue;
        }
    }

    return params;
}

/**
 * 分享此笔记
 */
function shareNote() {
    if (!Trees.value.tree[contentSelectIndex.value])
        return Clipboard.copy(window.location.href);
    Clipboard.copy(
        window.location.origin +
            "?path=" +
            Trees.value.tree[contentSelectIndex.value].path
    );
}

// let container: any = null;
// function initMonaco() {
//     const container = document.getElementById("container");
//     if (container) {
//         const myEditor = monaco.editor.create(container, {
//             value: testValue.value,
//             language: "markdown",
//             automaticLayout: true,
//             theme: "vs-dark"
//         });
//         myEditor.onKeyDown(() => {
//             console.log(myEditor.getValue());
//         });
//     }
// }
</script>

<style lang="less">
/* 全局样式 */
* {
    margin: 0;
    padding: 0;
    word-break: break-all;
    outline: none;
    user-select: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    -o-user-select: none;
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    -webkit-tap-highlight-color: transparent;
    -webkit-user-select: text !important;
}

[v-cloak] {
    display: none;
}

html,
body,
#app,
#app2,
.el-container {
    height: 100%;
}

a {
    text-decoration: none;
    color: black;
}

img {
    max-width: 100%;
    max-height: 400px;
    cursor: pointer;
}

code {
    white-space: pre-wrap;
}

.language-js span,
code,
code * {
    font-family: "Fira Code" !important;
}

/* 统一过渡 */
.treesItem,
.bottomMenu > div::before,
.leftMenu,
.main,
.content,
.peBlackHide,
.contentItem,
.content a::after,
.editorMenu i,
.editor {
    transition: all 0.3s ease-in-out;
    -webkit-transition: all 0.3s ease-in-out;
    -moz-transition: all 0.3s ease-in-out;
    -ms-transition: all 0.3s ease-in-out;
    -o-transition: all 0.3s ease-in-out;
}

/* 按钮过渡 */
.bottomMenu > div,
.content img {
    transition: all 0.1s ease-in-out;
    -webkit-transition: all 0.1s ease-in-out;
    -moz-transition: all 0.1s ease-in-out;
    -ms-transition: all 0.1s ease-in-out;
    -o-transition: all 0.1s ease-in-out;
}

/* 主体 */
.main {
    height: 100%;
    display: flex;
    overflow: hidden;
    position: relative;
}

/* 左侧 */
.leftMenu {
    width: 0;
    min-width: 0;
    max-width: 350px;
    position: relative;
    height: 100%;
    z-index: 2;
}

.leftMenuHide {
    width: 30%;
    min-width: 230px;
}

.el-tabs,
.el-tabs__content,
.el-tab-pane {
    height: calc(100% - 20px) !important;
}

/* 菜单 */
.el-icon-arrow-left:before,
.el-icon-arrow-right:before,
.el-tabs__nav-wrap::after {
    visibility: hidden !important;
}

.leftMenuHide .el-icon-arrow-left:before,
.leftMenuHide .el-icon-arrow-right:before,
.leftMenuHide .el-tabs__nav-wrap::after {
    visibility: inherit !important;
}

.el-tabs__header {
    box-sizing: border-box !important;
    overflow: hidden;
}

/* 文件树 */
.el-tab-pane {
    overflow-y: scroll !important;
}

/* 文件列表头部 */
.treesHead {
    margin: 0 0 5px 15px;
}

/* 文件列表 */
.treesItem {
    padding: 8px 5px 8px 30px;
    box-sizing: border-box;
    cursor: pointer;
    opacity: 0.5;
}

/* 目录 */
.contentTrees {
    padding: 0 15px;
}

.contentItem {
    padding: 5px;
    cursor: pointer;
    opacity: 0.5;
}

.contentTrees .H2 {
    padding-left: 20px;
}

.contentTrees .H3 {
    padding-left: 30px;
}

.contentTrees .H4 {
    padding-left: 40px;
}

/* 手机端遮罩 */
.peBlack {
    position: absolute;
    z-index: 1;
    width: 100%;
    height: 100%;
    opacity: 0;
    visibility: hidden;
    background: transparent;
    display: none;
}

.peBlackHide {
    opacity: 1;
    visibility: initial;
    background: rgba(0, 0, 0, 0.3);
}

/* 内容 */
.body {
    width: 100%;
    height: 100%;
    overflow: hidden;
    display: flex;
}

/* 编辑器 */
.editor {
    min-width: 0;
    width: 0;
    height: 100%;
    background-color: var(--bg-color);
    box-shadow: 3px 0 3px rgba(0, 0, 0, 0.2);
    z-index: 1;
    color: var(--text-color1);
    overflow: hidden;
}

.editorShow {
    min-width: 45%;
}

.editorMenu {
    border-bottom: 2px solid var(--bg-color5);
    display: flex;
    align-items: center;
    padding: 0 10px;
}

.editorMenu i {
    padding: 10px;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    -ms-border-radius: 5px;
    -o-border-radius: 5px;
    cursor: pointer;
}

.editorMenu i:hover {
    background: var(--menu-hover);
}

.editor > textarea,
.editor #container {
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    border: none;
    background: transparent;
    color: var(--text-color1);
}

/* 文章内容 */
.content {
    width: 100%;
    height: 100%;
    padding: 0 80px 50px;
    box-sizing: border-box;
    overflow-y: scroll;
}

/* 加载 */
.loading {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.loading p::before {
    content: "";
    display: block;
    width: 20px;
    height: 20px;
    background-color: black;
    margin: 10px auto;
    border-radius: 50%;
    -webkit-border-radius: 50%;
    -moz-border-radius: 50%;
    -ms-border-radius: 50%;
    -o-border-radius: 50%;
    animation: loading 0.8s ease-in-out infinite;
    -webkit-animation: loading 0.8s ease-in-out infinite;
}

@keyframes loading {
    0% {
        transform: scale(1);
        -webkit-transform: scale(1);
        -moz-transform: scale(1);
        -ms-transform: scale(1);
        -o-transform: scale(1);
    }

    50% {
        transform: scale(1.5);
        -webkit-transform: scale(1.5);
        -moz-transform: scale(1.5);
        -ms-transform: scale(1.5);
        -o-transform: scale(1.5);
    }

    100% {
        transform: scale(1);
        -webkit-transform: scale(1);
        -moz-transform: scale(1);
        -ms-transform: scale(1);
        -o-transform: scale(1);
    }
}

/* 底部菜单 */
.bottomMenu {
    position: absolute;
    bottom: 20px;
    right: 0;
    z-index: 2;
    transform: translateX(100%);
    -webkit-transform: translateX(100%);
    -moz-transform: translateX(100%);
    -ms-transform: translateX(100%);
    -o-transform: translateX(100%);
}

.bottomMenu > div {
    width: 35px;
    height: 35px;
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 15px 0;
    cursor: pointer;
    border-radius: 0 20px 20px 0;
    -webkit-border-radius: 0 20px 20px 0;
    -moz-border-radius: 0 20px 20px 0;
    -ms-border-radius: 0 20px 20px 0;
    -o-border-radius: 0 20px 20px 0;
}

.bottomMenu > div:active {
    transform: scale(0.9);
    -webkit-transform: scale(0.9);
    -moz-transform: scale(0.9);
    -ms-transform: scale(0.9);
    -o-transform: scale(0.9);
}

.bottomMenu > div::before {
    content: attr(content);
    display: block;
    position: absolute;
    right: 0;
    white-space: nowrap;
    transform: translateX(80%);
    -webkit-transform: translateX(80%);
    -moz-transform: translateX(80%);
    -ms-transform: translateX(80%);
    -o-transform: translateX(80%);
    opacity: 0;
    padding: 3px 10px;
    border-radius: 10px;
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    -ms-border-radius: 10px;
    -o-border-radius: 10px;
}

.bottomMenu > div:hover::before {
    transform: translateX(110%);
    -webkit-transform: translateX(110%);
    -moz-transform: translateX(110%);
    -ms-transform: translateX(110%);
    -o-transform: translateX(110%);
    opacity: 1;
}

.bottomMenu i {
    font-size: 1.2rem;
}

@media screen and (max-width: 820px) {
    .leftMenu {
        position: absolute;
        z-index: 2;
    }

    .content {
        padding: 50px 10%;
    }

    .peBlack {
        display: block;
    }
}

@media screen and (max-width: 450px) {
    .leftMenuHide {
        width: 80%;
        min-width: 230px;
    }

    .content {
        padding: 50px 5%;
    }
}

/* 代码块 */
pre {
    position: relative;
}

pre code ul {
    list-style: decimal;
}

pre code ul li {
    padding-left: 10px;
}

/* 图片查看背景模糊 */
.viewer-backdrop {
    backdrop-filter: blur(20px);
}
</style>

<style>
:root {
    --scrollbar-track-color: rgba(95, 97, 101, 0.3);
    --text-color1: black;
    --bg-color: #f5f5f5;
    --text-color3: black;
    --bg-color5: #e9e9e9;
    --active-color: black;
    --table-thead-color: #dfe2e5;
    --table-border-color: #f8f8f8;
    --menu-hover: rgb(211, 211, 211);

    .hljs {
        color: #383a42;
    }

    .hljs-comment,
    .hljs-quote {
        color: #a0a1a7;
        font-style: italic;
    }

    .hljs-doctag,
    .hljs-formula,
    .hljs-keyword {
        color: #a626a4;
    }

    .hljs-deletion,
    .hljs-name,
    .hljs-section,
    .hljs-selector-tag,
    .hljs-subst {
        color: #e45649;
    }

    .hljs-literal {
        color: #0184bb;
    }

    .hljs-addition,
    .hljs-attribute,
    .hljs-meta .hljs-string,
    .hljs-regexp,
    .hljs-string {
        color: #50a14f;
    }

    .hljs-attr,
    .hljs-number,
    .hljs-selector-attr,
    .hljs-selector-class,
    .hljs-selector-pseudo,
    .hljs-template-variable,
    .hljs-type,
    .hljs-variable {
        color: #986801;
    }

    .hljs-bullet,
    .hljs-link,
    .hljs-meta,
    .hljs-selector-id,
    .hljs-symbol,
    .hljs-title {
        color: #4078f2;
    }

    .hljs-built_in,
    .hljs-class .hljs-title,
    .hljs-title.class_ {
        color: #c18401;
    }

    .hljs-emphasis {
        font-style: italic;
    }

    .hljs-strong {
        font-weight: 700;
    }

    .hljs-link {
        text-decoration: underline;
    }
}

* {
    font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
        "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
}

/* 首次加载 */
.loading {
    color: var(--active-color);
    background-color: var(--bg-color);
}

/* 加载小球 */
.loading p::before {
    background-color: var(--active-color);
}

/* 滚动条 */
::-webkit-scrollbar {
    width: 8px;
    padding-right: 10px;
    background-color: rgba(0, 0, 0, 0);
}

::-webkit-scrollbar-track:hover {
    background-color: var(--scrollbar-track-color) !important;
    border-radius: 4px;
}

::-webkit-scrollbar-thumb,
::-webkit-scrollbar-thumb:active {
    background-color: var(--active-color) !important;
    border-radius: 4px;
}

/* 左侧目录树背景 与 阴影 */
.leftMenu {
    color: var(--text-color1);
    background-color: var(--bg-color);
    box-shadow: 3px 0 3px rgba(0, 0, 0, 0.2);
}

/* 目录右下角菜单 */
.bottomMenu > div,
.bottomMenu > div::before {
    color: var(--text-color1);
    background-color: var(--bg-color);
    box-shadow: 5px 0 5px rgba(0, 0, 0, 0.3);
}

/* 加载遮罩背景颜色 */
.el-loading-mask {
    background-color: rgba(212, 212, 212, 0.5) !important;
    backdrop-filter: blur(5px) !important;
}

/* 加载图标颜色 */
.el-loading-spinner .path {
    stroke: var(--active-color) !important;
}

/* 加载文字颜色 */
.el-input-number__decrease:hover,
.el-input-number__increase:hover,
.el-loading-spinner .el-loading-text,
.el-loading-spinner i {
    color: var(--active-color) !important;
}

/* tab 边距 */
.el-tabs__nav-scroll {
    padding: 0 15px !important;
}

/* 左侧目录菜单字体颜色 */
.el-tabs__item {
    color: var(--text-color3) !important;
}

/* 左侧目录菜单字体 选中颜色 */
.el-tabs__item.is-active,
.el-tabs__item:hover {
    color: var(--text-color1) !important;
}

/* 左侧目录菜单线条颜色 */
.el-tabs__nav-wrap::after {
    background-color: var(--bg-color5) !important;
}

/* 左侧目录菜单线条 选中颜色 */
.el-tabs__active-bar {
    background-color: var(--text-color1) !important;
}

/* 左侧顶部跳转仓库 */
.treesHead a {
    color: var(--text-color1);
}

/* 笔记悬浮样式 */
.treesItem:hover {
    opacity: 1;
    border-left: 5px solid var(--active-color);
}

/* 选中笔记样式 */
.treesItemActive {
    opacity: 1;
    background-color: var(--bg-color5);
    border-left: 5px solid var(--active-color);
}

/* 目录未选中 */
.contentItem {
    opacity: 0.5;
}

/* 目录选中 */
.contentItemActive {
    opacity: 1;
    font-weight: bold;
}

/* 内容页 */
.content {
    background-color: var(--bg-color);
    color: var(--text-color1);
}

/* .content 编辑器样式 */
.content a {
    color: #4183c4;
    position: relative;
}

.content a::after {
    content: "";
    display: block;
    width: 0;
    height: 2px;
    position: absolute;
    bottom: -3px;
    left: 50%;
    background-color: #4183c4;
    transform: translateX(-50%);
    -webkit-transform: translateX(-50%);
    -moz-transform: translateX(-50%);
    -ms-transform: translateX(-50%);
    -o-transform: translateX(-50%);
}

.content a:hover::after {
    width: 100%;
}

.content img {
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    -ms-border-radius: 5px;
    -o-border-radius: 5px;
    margin: 10px 0;
}

.content img:hover {
    transform: scale(1.02);
    -webkit-transform: scale(1.02);
    -moz-transform: scale(1.02);
    -ms-transform: scale(1.02);
    -o-transform: scale(1.02);
    box-shadow:
        rgba(50, 50, 93, 0.25) 0px 6px 12px -2px,
        rgba(0, 0, 0, 0.3) 0px 3px 7px -3px;
}

.content h1,
.content h2,
.content h3,
.content h4,
.content h5,
.content h6 {
    position: relative;
    margin-top: 1.5rem;
    margin-bottom: 1.5rem;
    padding: 10px 0;
    font-weight: bold;
    line-height: 1.4;
    cursor: text;
}

.content h1:hover a.anchor,
.content h2:hover a.anchor,
.content h3:hover a.anchor,
.content h4:hover a.anchor,
.content h5:hover a.anchor,
.content h6:hover a.anchor {
    text-decoration: none;
}

.content h1 tt,
.content h1 code {
    font-size: inherit;
}

.content h2 tt,
.content h2 code {
    font-size: inherit;
}

.content h3 tt,
.content h3 code {
    font-size: inherit;
}

.content h4 tt,
.content h4 code {
    font-size: inherit;
}

.content h5 tt,
.content h5 code {
    font-size: inherit;
}

.content h6 tt,
.content h6 code {
    font-size: inherit;
}

.content h1 {
    font-size: 2.25em;
    line-height: 1.2;
    border-bottom: 1px solid #bebebe;
}

.content h2 {
    font-size: 1.75em;
    line-height: 1.225;
    border-bottom: 1px solid #bebebe;
}

.content h3 {
    font-size: 1.5em;
    line-height: 1.43;
}

.content h4 {
    font-size: 1.25em;
}

.content h5 {
    font-size: 1em;
}

.content h6 {
    font-size: 1em;
    color: #777;
}

.content p,
.content blockquote,
.content ul,
.content ol,
.content dl,
.content table {
    margin: 0.8em 0;
}

.content li > ol,
.content li > ul {
    margin: 0 0;
}

.content hr {
    height: 2px;
    padding: 0;
    margin: 16px 0;
    background-color: #e7e7e7;
    border: 0 none;
    overflow: hidden;
    box-sizing: content-box;
}

.content li p.first {
    display: inline-block;
}

.content ul,
.content ol {
    padding-left: 30px;
}

.content ul:first-child,
.content ol:first-child {
    margin-top: 0;
}

.content ul:last-child,
.content ol:last-child {
    margin-bottom: 0;
}

.content blockquote {
    border-left: 4px solid var(--active-color);
    padding: 0 15px;
    color: #777777;
}

.content blockquote blockquote {
    padding-right: 0;
}

.content table {
    padding: 0;
    word-break: initial;
    border-collapse: collapse;
}

.content table thead tr {
    background-color: var(--table-thead-color);
}

.content table tr th {
    font-weight: bold;
    border-left: 2px solid var(--table-border-color);
    border-right: 2px solid var(--table-border-color);
    text-align: left;
    margin: 0;
    padding: 6px 13px;
}

.content table tbody tr {
    border-top: 2px solid var(--table-border-color);
    margin: 0;
    padding: 0;
}

.content table tbody tr:nth-child(2n) {
    background-color: var(--bg-color5);
}

.content table tbody tr:nth-child(2n + 1) {
    background-color: var(--bg-color5);
}

.content table tr td {
    border-left: 2px solid var(--table-border-color);
    border-right: 2px solid var(--table-border-color);
    text-align: left;
    margin: 0;
    padding: 6px 13px;
}

.content table tr th:first-child,
.content table tr td:first-child {
    border-left-width: 0px;
}

.content table tr th:last-child,
.content table tr td:last-child {
    border-right-width: 0px;
}

.content code,
.content tt {
    background-color: var(--bg-color5);
    border-radius: 3px;
    padding: 0;
    padding: 2px 4px 0px 4px;
    font-size: 0.9em;
}

.content code {
    background-color: var(--bg-color5);
    padding: 0 2px 0 2px;
}

.content p code {
    font-size: 0.9em;
    background-color: var(--bg-color5);
    padding: 0.3em;
    padding-top: 0.15em;
    padding-bottom: 0.15em;
    border-radius: 0.25rem;
}

.content pre {
    background-color: var(--bg-color5);
    padding: 0 20px;
    box-sizing: border-box;
}

.content kbd {
    background: var(--bg-color5);
    color: var(--text-color1);
    box-shadow: 0 3px 0 var(--scrollbar-track-color);
    padding: 2px 8px;
    margin: 0 3px;
}

code ul li::marker {
    color: gray;
}

p {
    line-height: 1.5rem;
}

:root[theme="dark"] {
    --scrollbar-track-color: rgba(95, 97, 101, 0.3);
    --text-color1: #e6e6e6;
    --bg-color: #292a2b;
    --text-color3: #757575;
    --bg-color5: #303233;
    --active-color: #2996ff;
    --table-thead-color: #2b2d2e;
    --table-border-color: #555;
    --bg-color1: #292a2b;
    --menu-hover: rgb(34, 34, 34);

    /* 加载遮罩背景颜色 */
    .el-loading-mask {
        background-color: rgba(0, 0, 0, 0.6) !important;
        backdrop-filter: blur(5px) !important;
    }

    .hljs {
        color: #abb2bf;
    }

    .hljs-comment,
    .hljs-quote {
        color: #5c6370;
        font-style: italic;
    }

    .hljs-doctag,
    .hljs-formula,
    .hljs-keyword {
        color: #c678dd;
    }

    .hljs-deletion,
    .hljs-name,
    .hljs-section,
    .hljs-selector-tag,
    .hljs-subst {
        color: #e06c75;
    }

    .hljs-literal {
        color: #56b6c2;
    }

    .hljs-addition,
    .hljs-attribute,
    .hljs-meta .hljs-string,
    .hljs-regexp,
    .hljs-string {
        color: #98c379;
    }

    .hljs-attr,
    .hljs-number,
    .hljs-selector-attr,
    .hljs-selector-class,
    .hljs-selector-pseudo,
    .hljs-template-variable,
    .hljs-type,
    .hljs-variable {
        color: #d19a66;
    }

    .hljs-bullet,
    .hljs-link,
    .hljs-meta,
    .hljs-selector-id,
    .hljs-symbol,
    .hljs-title {
        color: #61aeee;
    }

    .hljs-built_in,
    .hljs-class .hljs-title,
    .hljs-title.class_ {
        color: #e6c07b;
    }

    .hljs-emphasis {
        font-style: italic;
    }

    .hljs-strong {
        font-weight: 700;
    }

    .hljs-link {
        text-decoration: underline;
    }
}

.copyBtn {
    position: absolute;
    right: 27px;
    top: 16px;
    padding: 5px 10px;
    background-color: var(--bg-color);
    cursor: pointer;
    user-select: none;
    border-radius: 5px;
}
</style>
